package org.zoomdev.zoom.dao.impl;

import org.zoomdev.zoom.dao.Record;
import org.zoomdev.zoom.dao.Values;
import org.zoomdev.zoom.dao.alias.NameAdapter;
import org.zoomdev.zoom.dao.utils.DaoUtils;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class ActiveRecordUtils {

    public static Integer executeUpdate(Connection connection, String sql,
                                        List<Object> values,
                                        boolean output) throws SQLException {
        PreparedStatement ps = null;
        try {
            ps = StatementUtils.prepareStatement(connection, sql, values, output);
            return ps.executeUpdate();
        } finally {
            DaoUtils.close(ps);
        }
    }

    public static Integer executeInsert(Connection connection,
                                        Record record,
                                        String sql,
                                        List<Object> values,
                                        String[] generatedKeys,
                                        boolean output) throws SQLException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            if (output) {
                RecordSqlUtils.logSql(sql, values);
            }
            ps = connection.prepareStatement(sql, generatedKeys);
            StatementUtils.prepareStatement(ps, values);
            int ret = ps.executeUpdate();
            if (ret > 0) {
                rs = ps.getGeneratedKeys();
                if (rs.next()) {
                    for (int i = 0; i < generatedKeys.length; ++i) {
                        Object value = rs.getObject(i + 1);
                        record.put(generatedKeys[i], value);
                    }
                }
            }
            return ret;
        } finally {
            DaoUtils.close(rs);
            DaoUtils.close(ps);
        }
    }

    static Integer execute(Connection connection, String sql, boolean output) throws SQLException {
        if (output) {
            RecordSqlUtils.logSql(sql);
        }
        Statement statement = null;
        try {
            statement = connection.createStatement();
            return statement.executeUpdate(sql);
        } finally {
            DaoUtils.close(statement);
        }
    }

    static Object executeGetValue(
            Connection connection,
            String sql,
            List<Object> values,
            boolean output) throws SQLException {

        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = StatementUtils.prepareStatement(connection, sql, values, output);
            rs = ps.executeQuery();
            if (rs.next()) {
                Object r = rs.getObject(1);
                return r;
            }
            return null;
        } finally {
            DaoUtils.close(rs);
            DaoUtils.close(ps);
        }


    }

    static final Values executeGetValues(Connection connection,
                                         String sql,
                                         List<Object> values,
                                         boolean output) throws SQLException {

        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = StatementUtils.prepareStatement(connection, sql, values, output);
            rs = ps.executeQuery();
            if (rs.next()) {
                ResultSetMetaData rsmd = rs.getMetaData();
                int columnCount = rsmd.getColumnCount();
                List<Object> data = new ArrayList<>();
                for (int i = 0; i < columnCount; ++i) {
                    data.add(rs.getObject(i + 1));
                }
                return new Values(data);
            }

            return null;
        } finally {
            DaoUtils.close(rs);
            DaoUtils.close(ps);
        }

    }

    static final Record executeGet(Connection connection,
                                   String sql,
                                   List<Object> values,
                                   NameAdapter nameAdapter,
                                   boolean output) throws SQLException {

        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = StatementUtils.prepareStatement(connection, sql, values, output);
            rs = ps.executeQuery();
            if (rs.next()) {
                return RecordUtils.buildOne(rs, nameAdapter);
            }
            return null;
        } finally {
            DaoUtils.close(rs);
            DaoUtils.close(ps);
        }
    }

    static final List<Record> executeQuery(Connection connection,
                                           String sql,
                                           List<Object> values,
                                           NameAdapter nameAdapter,
                                           boolean output) throws SQLException {

        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = StatementUtils.prepareStatement(connection, sql, values, output);
            rs = ps.executeQuery();
            return RecordUtils.build(rs, nameAdapter);
        } finally {
            DaoUtils.close(rs);
            DaoUtils.close(ps);
        }

    }


}
